#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: set et sw=4 fenc=utf-8:

# wxvfb.py - Virtual Frame Buffer
# Copyright (C) 2009 by Homin Lee <ff4500@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

import wx
from bufferedcanvas import *

import mmap
import os

class FrameBufferCanvas(BufferedCanvas):

    _bitmap = None # frame buffer contents

    def __init__(self,parent,ID=-1):
        BufferedCanvas.__init__(self,parent,ID)
        self.SetFocus()
    
    def draw(self, dc):
        if self._bitmap:
            dc.DrawBitmap(self._bitmap, 0, 0)

    def updateBitmap(self, bitmap):
        self._bitmap = bitmap
        self.update()


class TestFrame(wx.Frame):

    def __init__(self,
                 parent=None,
                 ID=-1,
                 title="",
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.DEFAULT_FRAME_STYLE,
                 mmfile="dummy.vfb"):
        wx.Frame.__init__(self,parent,ID,title,pos,size,style)
        self.canvas = FrameBufferCanvas(self)
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.Bind(wx.EVT_IDLE, self.onIdle)

        #Initialize mmap
        self._size = size
        bufLen = size[0]*size[1]*3
        fp = open(mmfile, 'w')
        fp.write('\x00'*bufLen)
        fp.close()
        fp = open(mmfile, 'r+')
        self._fbMap = mmap.mmap(fp.fileno(), bufLen)
        fp.close()

    def onClose(self, event):
        self.Show(False)
        self.Destroy()

    def onIdle(self, event):
        bitmap = wx.BitmapFromBuffer(self._size[0], self._size[1], self._fbMap)
        self.canvas.updateBitmap(bitmap)


def main(size, mmfile):
    app = wx.PySimpleApp()
    title = "Virtual Frame Buffer %dx%d - %s"%\
        (size[0], size[1], os.path.basename(mmfile))
    frame = TestFrame(title=title, size = size, mmfile=mmfile)
    frame.Show(True)
    app.SetTopWindow(frame)
    app.MainLoop()


if __name__ == '__main__':
    from optparse import OptionParser as OptPsr
    usage = "usage: %prog [opitons]"
    optPsr = OptPsr(usage)
    optPsr.add_option('-w', '--width', type='int', default=640,
		    help='width (default: 640)')
    optPsr.add_option('-g', '--height', type='int', default=480,
		    help='height (default: 480)')
    optPsr.add_option('-f', '--mmfile', type='str', default="dummy.vfb",
    		    help='file for mmap (default: dummy.vfb)')
    (opts, args) = optPsr.parse_args()

    main((opts.width, opts.height), opts.mmfile)
